home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 351-375 / disk_351 / pdc / libsrc.lzh / LibSrc / StdIO / bufmgt.c next >
C/C++ Source or Header  |  1990-04-07  |  4KB  |  185 lines

  1. /*
  2.  * Libraries and headers for PDC release 3.3 (C) 1989 Lionel Hummel.
  3.  * PDC Software Distribution (C) 1989 Lionel Hummel and Paul Petersen.
  4.  * PDC I/O Library (C) 1987 by J.A. Lydiatt.
  5.  *
  6.  * This code is freely redistributable upon the conditions that this 
  7.  * notice remains intact and that modified versions of this file not
  8.  * be included as part of the PDC Software Distribution without the
  9.  * express consent of the copyright holders.  No warrantee of any
  10.  * kind is provided with this code.  For further information, contact:
  11.  *
  12.  *  PDC Software Distribution    Internet:                     BIX:
  13.  *  P.O. Box 4006             or hummel@cs.uiuc.edu            lhummel
  14.  *  Urbana, IL  61801-8801       petersen@uicsrd.csrd.uiuc.edu
  15.  */
  16.  
  17. /*  bufmgt.c
  18.  *
  19.  *  Performs buffer management for PDC's stdio facilities
  20.  */
  21.  
  22. #include <stdio.h>
  23.  
  24. extern void (*_fcloseall)(), free();
  25. extern int fclose();
  26. extern int read(), write();
  27.  
  28. /*    Our internal routine to close all buffered I/O
  29.  */
  30. static void fcloseall()
  31. {
  32.     FILE *fp, *fp2;
  33.  
  34.     for ( fp = (FILE *) &_fdevtab[0]; fp != NULL; fp = fp2 ) {
  35.         fp2 = fp->next;
  36.         fclose( fp );
  37.     }
  38. }
  39.  
  40.  
  41. FILE *addStream()
  42. {
  43.     FILE *fp, *fp1;
  44.     extern char *malloc();
  45.  
  46.     /* If we're going to open a stream, there should be a routine to
  47.      * close it before the program exits.  If there isn't one already,
  48.      * provide our own.
  49.      */
  50.     if (!_fcloseall)
  51.         _fcloseall = &fcloseall;
  52.  
  53.     /*
  54.      * Try to nab an unused buffer
  55.      */
  56.     fp = (FILE *) &_fdevtab[0];
  57.     while( fp != 0L ) {
  58.         fp1 = fp;
  59.         if ( !fp->_fileflag )
  60.             break;
  61.         fp = fp->next;
  62.     }
  63.  
  64.     /*
  65.      * If fp is null, then there isn't an empty buffer - make one
  66.      * and link it into the chain.
  67.      */
  68.  
  69.     if ( fp == NULL ) {
  70.         fp = (FILE *) malloc(sizeof(FILE));
  71.         if ( fp == NULL )
  72.             return NULL;
  73.         fp1->next = fp;
  74.         fp->next = NULL;
  75.     }
  76.  
  77.     fp->_filecpos = NULL;
  78.     fp->_fileend = NULL;
  79.     fp->_filebufp = NULL;
  80.     fp->_fileflag = 0;
  81.     return fp;
  82. }
  83.  
  84.  
  85. /* Allocate a buffer to use with the given I/O stream:
  86.  */
  87. addStreamBuf( fp )
  88. FILE *fp;
  89. {
  90.     char *buffer;
  91.     extern char *malloc();
  92.  
  93.     if ( !(fp->_filebufp = malloc(BUFSIZ)) ) {
  94.         fp->_filebufp = &fp->_filebyte;
  95.         fp->_filelen = 1;
  96.     } else {
  97.         fp->_fileflag |= _FILEISDYNA;
  98.         fp->_filelen = BUFSIZ;
  99.     }
  100.  
  101.     if ( isatty((int)fp->_fileunit) )
  102.         fp->_fileflag |= _FILEISTTY;
  103.     
  104.     return;
  105. }
  106.  
  107.  
  108. int _filebfill( fp )
  109. FILE *fp;
  110. {
  111.     FILE *fp2;
  112.     int   len;
  113.  
  114.     if ( fp->_fileflag & (_FILEATEOF | _FILEBAD ) )
  115.     return EOF;
  116.  
  117.     fp->_fileflag &= ~_FILEISDIRTY;
  118.  
  119.     if ( fp->_filebufp == NULL )
  120.     addStreamBuf( fp );
  121.  
  122.     if ( fp->_fileflag & 0x80 ) {
  123.     for ( fp2= (FILE *) &_fdevtab[0]; fp2; fp2 = fp2->next)
  124.         if ( (fp->_fileflag & (0x80|_FILEISDIRTY)) == (0x80|_FILEISDIRTY) )
  125.         _doflush( fp2, -1 );
  126.     }
  127.  
  128.     len = read( (int)fp->_fileunit, fp->_filebufp, (int)fp->_filelen);
  129.     if ( len > 0 ) {
  130.     fp->_filecpos = fp->_filebufp;
  131.     fp->_fileend = fp->_filebufp + len;
  132.     return (*fp->_filecpos++ & 0xFF);
  133.     }
  134.  
  135.     if ( len < 0 )
  136.     fp->_fileflag |= _FILEBAD;
  137.     else
  138.     fp->_fileflag |= _FILEATEOF;
  139.     return EOF;
  140. }
  141.  
  142.  
  143. int _doflush( fp, data )
  144. FILE *fp;
  145. int  data;
  146. {
  147.     int  nchars;
  148.     char c = data;
  149.  
  150.     if ( fp->_fileflag & _FILEBAD )
  151.         return EOF;
  152.     if ( fp->_fileflag & _FILEISDIRTY ) {
  153.         nchars = fp->_filecpos - fp->_filebufp;
  154.         if ( write( (int)fp->_fileunit, fp->_filebufp, nchars ) != nchars )
  155.             goto err;
  156.     }
  157.  
  158.     if ( data == EOF ) {
  159.         fp->_fileflag &= ~_FILEISDIRTY;
  160.         fp->_filecpos = NULL;
  161.         fp->_fileend  = NULL;
  162.         return 0;
  163.     }
  164.  
  165.     if ( !fp->_filebufp )
  166.         addStreamBuf( fp );
  167.     if ( fp->_filelen == 1 ) {
  168.         if ( write( (int)fp->_fileunit, &c, 1 ) != 1 )
  169.             goto err;
  170.         return data;
  171.     }
  172.  
  173.     fp->_filecpos = fp->_filebufp;
  174.     fp->_fileend  = fp->_filebufp + fp->_filelen;
  175.     fp->_fileflag |= _FILEISDIRTY;
  176.     *fp->_filecpos++ = data;
  177.     return data;
  178.  
  179. err:
  180.     fp->_fileflag |= _FILEBAD;
  181.     fp->_filecpos = NULL;
  182.     fp->_fileend  = NULL;
  183.     return EOF;
  184. }
  185.